package com.abhipedro.wordsearch.model.dictionary;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * @author abhi
 * Stores all the words from raw langauge files to database. 
 * Provides list of words for given language.
 */
public class WordsDbAdapter {

	private Context mContext;
	private DatabaseHelper mDbHelper;
	private SQLiteDatabase mDb;

	private static String DATABASE_PATH = "/data/data/com.abhipedro.wordsearch.view/databases/";
	private final String DATABASE_NAME = "wordsearch.sqlite";
	private final int DB_VERSION = 1;
	private final String TABLE_ROW_ID = "id";
	private final String TABLE_ROW_ONE_NAME = "val";
	
	public WordsDbAdapter(Context context) {
		this.mContext = context;
	}

	/**
	 * Open the events database. If it cannot be opened, try to create a new
	 * instance of the database. If it cannot be created, throw an exception to
	 * signal the failure
	 * 
	 * @return this (self reference, allowing this to be chained in an
	 *         initialization call)
	 * @throws SQLException
	 *             if the database could be neither opened or created
	 */
	public WordsDbAdapter open() throws SQLException {
		mDbHelper = new DatabaseHelper(mContext);
		try {
			mDbHelper.createDataBase();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mDbHelper.openDataBase();
		return this;
	}

	public void close() {
		mDbHelper.close();
		mDb.close();
	}

	public SQLiteDatabase getWritableDatabase() {
		mDbHelper = new DatabaseHelper(mContext);
		try {
			mDbHelper.createDataBase();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mDbHelper.openDataBase();
		return mDb;
	}
	

	/**
	 *  Return 50 random letters for given language
	 * @param TABLE_NAME - table name for given language
	 */
	public ArrayList<String> getWordsForLang(String TABLE_NAME) {
		ArrayList<String> dataArrays = new ArrayList<String>();
		Cursor cursor = null;
		try {
			cursor = mDb.query(TABLE_NAME, new String[] { TABLE_ROW_ID,
					TABLE_ROW_ONE_NAME, }, null, null, null, null, "RANDOM() LIMIT 50");

			cursor.moveToFirst();
			if (!cursor.isAfterLast()) {
				do {
					dataArrays.add(cursor.getString(1));
				} while (cursor.moveToNext());
			}
		} catch (SQLException e) {
			Log.e("DB Error", e.toString());
			e.printStackTrace();
		} finally {
			if (null != cursor)
				cursor.close();
		}
		
		return dataArrays;
	}
	
	private class DatabaseHelper extends SQLiteOpenHelper {
		
		public DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DB_VERSION);
		}

		/**
		 * Creates a empty database on the system and rewrites it with your own
		 * database.
		 * */
		public void createDataBase() throws IOException {
			boolean dbExist = checkDataBase();
			if (dbExist) {
				// do nothing - database already exist
			} else {
				// By calling this method and empty database will be created into
				// the default system path of your application so we are going
				// be able to overwrite that database with our database.
				this.getWritableDatabase();
				try {
					copyDataBase();
				} catch (IOException e) {
					throw e;
					// throw new Error("Error copying database");
				}
			}

		}

		/**
		 * Check if the database already exist to avoid re-copying the file each
		 * time you open the application.
		 * 
		 * @return true if it exists, false if it doesn't
		 */
		private boolean checkDataBase() {
			SQLiteDatabase checkDB = null;
			try {
				String myPath = DATABASE_PATH + DATABASE_NAME;
				checkDB = SQLiteDatabase.openDatabase(myPath, null,
						SQLiteDatabase.OPEN_READONLY);
			} catch (SQLiteException e) {
				// database does't exist yet.
			}
			if (checkDB != null) {
				checkDB.close();
			}
			return checkDB != null ? true : false;
		}

		/**
		 * Copies your database from your local assets-folder to the just
		 * created empty database in the system folder, from where it can be
		 * accessed and handled. This is done by transfering bytestream.
		 * */
		private void copyDataBase() throws IOException {
			InputStream databaseInput = null;
			String outFileName = DATABASE_PATH + DATABASE_NAME;
			OutputStream databaseOutput = new FileOutputStream(outFileName);

			byte[] buffer = new byte[1024];
			int length;

			databaseInput = mContext.getAssets().open("wordsearch");
			while ((length = databaseInput.read(buffer)) > 0) {
				databaseOutput.write(buffer, 0, length);
				databaseOutput.flush();
			}
			databaseInput.close();

			databaseOutput.flush();
			databaseOutput.close();

		}

		public void openDataBase() throws SQLException {
			// Open the database
			String myPath = DATABASE_PATH + DATABASE_NAME;
			mDb = SQLiteDatabase.openDatabase(myPath, null,
					SQLiteDatabase.OPEN_READWRITE);

		}

		@Override
		public void onCreate(SQLiteDatabase db) {

		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

		}
	}
}